﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EpsiRisk.DonneesPlateau;

namespace EpsiRisk.MoteurJeu
{
    public abstract class ClassIntelligenceArtificielle
    {
        public static int distanceParArmeeTraversee(ClassSousTerritoire terSource, ClassSousTerritoire terDestination)
        {
            return distanceParArmeeTraverseeH(terSource, terDestination, terSource.Proprietaire, 20);
        }


        private static int distanceParArmeeTraverseeH(ClassSousTerritoire terSource, ClassSousTerritoire terDestination, ClassJoueur joueur, int profMax)
        {
            int dist = 0;
            if (terSource != terDestination)
            {
                if (profMax > 0)
                {
                    foreach (ClassSousTerritoire st in terSource.Voisins)
                    {
                        dist = Math.Min(dist, distanceParArmeeTraverseeH(st, terDestination, joueur, profMax - 1) + valuationArmeeTraverse(st, joueur));
                    }
                }
                else
                {
                    dist = 1000;
                }
            }
            return dist;
        }

        /// <summary>
        /// valeur correspondant a un pays traversé par un joueur
        /// </summary>
        /// <param name="st">pays traversé</param>
        /// <param name="joueur">joueur traversant le pays</param>
        /// <returns></returns>
        private static int valuationArmeeTraverse(ClassSousTerritoire st, ClassJoueur joueur)
        {
            if (joueur != st.Proprietaire)
            {
                return st.nbArmees;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// Accessibilité d'un pays(selon nombre de  liens)
        /// </summary>
        /// <param name="pays"></param>
        /// <param name="profondeur">profondeur de l'arbre d'accessibilité</param>
        /// <returns></returns>
        public static float accessibilitePays(ClassSousTerritoire pays, int profondeur)
        {
            float acc = pays.Voisins.Count;
            if (profondeur != 0)
                foreach (ClassSousTerritoire v in pays.Voisins)
                {
                    acc = acc + coeff_accessibilite_profondeur * accessibilitePays(v, profondeur - 1) / pays.Voisins.Count;
                }
            return acc;
        }

        const float coeff_accessibilite_profondeur = 0.33f;


        public static int choixNbTroupes(ClassSousTerritoire attaquant, ClassSousTerritoire attaqué)
        {
            int nbAttaquants = 1;
            switch (attaqué.nbArmees)
            {
                case 1:
                    break;
                case 2:
                    break;
                default:
                    break;
            }
            return nbAttaquants;
        }

        public static int payspossede_parcontinent(ClassTerritoire territoireaevaluer)
        {
            int nbpays = 0;

            foreach (ClassSousTerritoire sT in territoireaevaluer.ListeSousTerritoire)
            {
                if (sT.Proprietaire == ClassEtatPartie.joueurCourant())
                    nbpays++;
            }
            return nbpays;
        }

        public static List<ClassSousTerritoire> meilleur_regroupement()
        {
            List<ClassSousTerritoire> Listemeilleurterritoireregrouper;
            List<ClassSousTerritoire> Listeterritoireregrouper1 = pays_regrouper_par_continent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[0]);
            List<ClassSousTerritoire> Listeterritoireregrouper2 = pays_regrouper_par_continent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[1]);
            List<ClassSousTerritoire> Listeterritoireregrouper3 = pays_regrouper_par_continent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[2]);
            List<ClassSousTerritoire> Listeterritoireregrouper4 = pays_regrouper_par_continent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[3]);
            List<ClassSousTerritoire> Listeterritoireregrouper5 = pays_regrouper_par_continent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[4]);
            List<ClassSousTerritoire> Listeterritoireregrouper6 = pays_regrouper_par_continent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[5]);

            int oldindex = 0;
            int index = 0;
            Listemeilleurterritoireregrouper = Listeterritoireregrouper1;
            index = compare_regroupement(Listemeilleurterritoireregrouper, index, Listeterritoireregrouper2, 1);
            if (index != oldindex)
            {
                Listemeilleurterritoireregrouper = Listeterritoireregrouper2;
            }
            oldindex = index;
            index = compare_regroupement(Listemeilleurterritoireregrouper, index, Listeterritoireregrouper3, 2);
            if (index != oldindex)
            {
                Listemeilleurterritoireregrouper = Listeterritoireregrouper3;
            }
            oldindex = index;
            index = compare_regroupement(Listemeilleurterritoireregrouper, index, Listeterritoireregrouper4, 3);
            if (index != oldindex)
            {
                Listemeilleurterritoireregrouper = Listeterritoireregrouper4;
            }
            oldindex = index;
            index = compare_regroupement(Listemeilleurterritoireregrouper, index, Listeterritoireregrouper5, 4);
            if (index != oldindex)
            {
                Listemeilleurterritoireregrouper = Listeterritoireregrouper5;
            }
            oldindex = index;
            index = compare_regroupement(Listemeilleurterritoireregrouper, index, Listeterritoireregrouper6, 5);
            if (index != oldindex)
            {
                Listemeilleurterritoireregrouper = Listeterritoireregrouper6;
            }

            return Listemeilleurterritoireregrouper;
        }

        public static int compare_regroupement(List<ClassSousTerritoire> sT1, int indexcontinent1,List<ClassSousTerritoire> sT2, int indexcontinent2)
        {
            int index;

            index = indexcontinent1;
            if (payspossede_parcontinent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent2]) / ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent2].ListeSousTerritoire.Count > payspossede_parcontinent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent1]) / ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent1].ListeSousTerritoire.Count)
            {
                index = indexcontinent2;
            }
            else
            {
                if (payspossede_parcontinent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent2]) / ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent2].ListeSousTerritoire.Count == payspossede_parcontinent(ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent1]) / ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent1].ListeSousTerritoire.Count)
                {
                    if (sT2.Count > sT1.Count)
                    {
                        index = indexcontinent2;
                    }
                    else
                    {
                        if (sT2.Count == sT1.Count)
                        {
                            if (ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent2].ListeSousTerritoire.Count > ClassDonneesGlobales.plateauCourant.ListeTerritoires[indexcontinent1].ListeSousTerritoire.Count)
                            {
                                index = indexcontinent2;
                            }
                        }
                    }
                }
            }

            return index;
        }


        /// <summary>
        /// cherche le plus gros regroupement de pays dans un continent
        /// </summary>
        /// <param name="territoireaevaluer">continent a évaluer</param>
        /// <returns></returns>
        public static List<ClassSousTerritoire> pays_regrouper_par_continent(ClassTerritoire territoireaevaluer)
        {
            List<ClassSousTerritoire> ListeSousTerritoire;
            List<ClassSousTerritoire> Listeterritoireregrouper1 = new List<ClassSousTerritoire> { };
            List<ClassSousTerritoire> Listeterritoireregrouper2 = new List<ClassSousTerritoire> { };

            foreach (ClassSousTerritoire sTevaluer in territoireaevaluer.ListeSousTerritoire)
            {
                if (sTevaluer.Proprietaire == ClassEtatPartie.joueurCourant() && !Listeterritoireregrouper1.Contains(sTevaluer) && !Listeterritoireregrouper2.Contains(sTevaluer))
                {
                    if (Listeterritoireregrouper1.Count > Listeterritoireregrouper2.Count)
                    {
                        Listeterritoireregrouper2 = new List<ClassSousTerritoire> { };
                        Listeterritoireregrouper2.Add(sTevaluer);
                        foreach (ClassSousTerritoire sTvoisin in sTevaluer.Voisins)
                            if (sTvoisin.Proprietaire == ClassEtatPartie.joueurCourant() && !Listeterritoireregrouper1.Contains(sTvoisin))// && territoireaevaluer.ListeSousTerritoire.Contains(sTvoisin))
                            {
                                Listeterritoireregrouper2.Add(sTvoisin);
                            }
                    }
                    else
                    {
                        Listeterritoireregrouper1 = new List<ClassSousTerritoire> { };
                        Listeterritoireregrouper1.Add(sTevaluer);
                        foreach (ClassSousTerritoire sTvoisin in sTevaluer.Voisins)
                            if (sTvoisin.Proprietaire == ClassEtatPartie.joueurCourant() && !Listeterritoireregrouper1.Contains(sTvoisin))// && territoireaevaluer.ListeSousTerritoire.Contains(sTvoisin))
                            {
                                Listeterritoireregrouper1.Add(sTvoisin);
                            }
                    }
                }
            }
            if (Listeterritoireregrouper1.Count < Listeterritoireregrouper2.Count)
                ListeSousTerritoire = Listeterritoireregrouper2;
            else
                ListeSousTerritoire = Listeterritoireregrouper1;
            /*Console.Write("Test fonction pays_regrouper_par_continent :");
            foreach (ClassSousTerritoire sT in ListeSousTerritoire)
            {
                Console.Write(sT.Nom + "\r\n");
            }*/
            return ListeSousTerritoire;
        }

        public static int coefdistregroupement = 1;

        public static void eval_regroupement_pays(List<ClassSousTerritoire> lstaevaluer)
        {
            float coefTotal = 0;
            int count = lstaevaluer.Count();
            for (int i = 0; i < count; i++)
            {
                int nbEnnemi = 0;
                foreach (ClassSousTerritoire st in lstaevaluer[i].Voisins)
                {
                    if (st.Proprietaire != ClassEtatPartie.joueurCourant() && ClassDonneesGlobales.plateauCourant.getContinent(st)==ClassDonneesGlobales.plateauCourant.getContinent(lstaevaluer[0]))
                    {
                        nbEnnemi ++;
                    }
                }
                lstaevaluer[i].coefIA = 1 - (nbEnnemi / lstaevaluer[i].Voisins.Count);
                coefTotal += lstaevaluer[i].coefIA;
            }
            for (int i = 0; i < count; i++)
            {
                lstaevaluer[i].coefIA = lstaevaluer[i].coefIA / coefTotal;
            }
        }
    }
}
